bitkeeper revision 1.331.1.1 (3f0d5ce2ty7t1xKoi_XfrqGCd6L9mg)
authorsos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk>
Thu, 10 Jul 2003 12:32:34 +0000 (12:32 +0000)
committersos22@labyrinth.cl.cam.ac.uk <sos22@labyrinth.cl.cam.ac.uk>
Thu, 10 Jul 2003 12:32:34 +0000 (12:32 +0000)
Clean up segments when the domain dies.

xen/common/domain.c
xen/drivers/block/xen_segment.c
xen/include/xeno/segment.h

index d52835017e78aeb6018d12c88775cd0d44cea20e..06e67e7dc578b5523e1620a5d0b0488f7b795de1 100644 (file)
@@ -143,6 +143,9 @@ void __kill_domain(struct task_struct *p)
 
     unlink_blkdev_info(p);
 
+    for ( i = 0; i < XEN_MAX_SEGMENTS; i++ )
+       xen_segment_delete(p, i);
+
     for ( i = 0; i < MAX_DOMAIN_VIFS; i++ )
         unlink_net_vif(p->net_vif_list[i]);
 
index b4ccf0cf58463c29b3bb9baee29bbda93cd55ff0..74547abe2840d630ffc330b7884ce6e4457f2d02 100644 (file)
@@ -15,7 +15,7 @@
 #include <asm/domain_page.h>
 #include <hypervisor-ifs/block.h>
 
-segment_t xsegments[XEN_MAX_SEGMENTS];
+static segment_t xsegments[XEN_MAX_SEGMENTS];
 
 #if 0
 #define DPRINTK(_f, _a...) printk( _f , ## _a )
@@ -23,6 +23,9 @@ segment_t xsegments[XEN_MAX_SEGMENTS];
 #define DPRINTK(_f, _a...) ((void)0)
 #endif
 
+/* XXX XXX XXX Why are there absolutely no calls to any locking
+   primitives anywhere in this? */
+
 /*
  * xen_segment_map_request
  *
@@ -186,7 +189,6 @@ void xen_segment_probe_all(xen_segment_info_t *raw_xsi)
 {
     int loop;
     xen_segment_info_t *xsi = map_domain_mem(virt_to_phys(raw_xsi));
-    unsigned long device;
 
     xsi->count = 0;
     for ( loop = 0; loop < XEN_MAX_SEGMENTS; loop++ )
@@ -234,7 +236,6 @@ void xen_refresh_segment_list (struct task_struct *p)
  * if we see the same DOM#/SEG# combination, we reuse the slot in
  * the segment table (overwriting what was there before).
  * an alternative would be to raise an error if the slot is reused.
- * bug: we don't free the xtents array when we re-use a slot.
  */
 int xen_segment_create(xv_disk_t *xvd_in)
 {
@@ -261,6 +262,8 @@ int xen_segment_create(xv_disk_t *xvd_in)
     xsegments[idx].segment_number = xvd->segment;
     memcpy(xsegments[idx].key, xvd->key, XEN_SEGMENT_KEYSIZE);
     xsegments[idx].num_extents = xvd->ext_count;
+    if (xsegments[idx].extents)
+       kfree(xsegments[idx].extents);
     xsegments[idx].extents = (extent_t *)kmalloc(
         sizeof(extent_t)*xvd->ext_count,
         GFP_KERNEL);
@@ -296,10 +299,43 @@ int xen_segment_create(xv_disk_t *xvd_in)
  *
  * return 0 on success, 1 on failure
  *
- * TODO: caller must ensure that only domain 0 calls this function
  */
-int xen_segment_delete(struct task_struct *p, xv_disk_t *xvd)
+int xen_segment_delete(struct task_struct *p, int segnr)
 {
+    segment_t *seg;
+
+    if (!p) {
+       printk("xen_segment delete called with NULL domain?\n");
+       BUG();
+       return 1;
+    }
+
+    if (segnr < 0 || segnr > XEN_MAX_SEGMENTS) {
+       printk("xen_segment_delete called with bad segnr?\n");
+       BUG();
+       return 1;
+    }
+
+    if (!p->segment_list[segnr])
+       return 1;
+
+    seg = p->segment_list[segnr];
+
+    /* sanity checking */
+    if (seg->domain != p->domain || seg->segment_number != segnr ||
+       (seg->mode != XEN_SEGMENT_RO && seg->mode != XEN_SEGMENT_RW) ||
+       seg->num_extents <= 0 || seg->extents == NULL) {
+       printk("segment is insane!\n");
+       BUG();
+       return 1;
+    }
+
+    p->segment_list[segnr] = NULL;
+    seg->domain = -1;
+    seg->segment_number = -1;
+    kfree(seg->extents);
+    seg->mode = XEN_SEGMENT_UNUSED;
+
     return 0;
 }
 
index 6e702816acda3537ec987b58cfa9c1bb3db91426..bb3437e1e846bd6f755302c61f6766d592a5994d 100644 (file)
@@ -17,6 +17,7 @@ struct task_struct;
 void xen_segment_initialize(void);
 void xen_refresh_segment_list (struct task_struct *p);
 int xen_segment_create(xv_disk_t *xvd);
+int xen_segment_delete(struct task_struct *p, int segnr);
 int xen_segment_map_request(
     phys_seg_t *pseg, struct task_struct *p, int operation,
     unsigned short segment_number,